/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "client_sec_storage.h"

#include <securec.h>

#include "client_base.h"
#include "logger.h"
#include "sec_storage_ipc_proxy.h"

PUBLIC_API ResultCode SeSecStorageSetFactoryResetAuthenticationKey(FactoryResetLevel level, FactoryResetAuthAlgo algo,
    const StorageAuthKey *key)
{
    return SeSecStorageSetFactoryResetAuthenticationKeyProxy(SendRequestToServer, level, algo, key);
}

PUBLIC_API ResultCode SeSecStorageGetFactoryResetAuthenticationAlgo(FactoryResetLevel level, FactoryResetAuthAlgo *algo)
{
    return SeSecStorageGetFactoryResetAuthenticationAlgoProxy(SendRequestToServer, level, algo);
}

PUBLIC_API ResultCode SeSecStoragePrepareFactoryReset(uint8_t *nonce, uint32_t *length)
{
    return SeSecStoragePrepareFactoryResetProxy(SendRequestToServer, nonce, length);
}

PUBLIC_API ResultCode SeSecStorageProcessFactoryReset(FactoryResetLevel level, const uint8_t *credential,
    uint32_t length)
{
    return SeSecStorageProcessFactoryResetProxy(SendRequestToServer, level, credential, length);
}

PUBLIC_API ResultCode SeSecStorageSetToUserMode(const StorageUserModeConf *config)
{
    return SeSecStorageSetToUserModeProxy(SendRequestToServer, config);
}

PUBLIC_API ResultCode SeSecStorageIsSlotOperateAlgorithmSupported(SlotOperAlgo algo, uint32_t *avaliable)
{
    return SeSecStorageIsSlotOperateAlgorithmSupportedProxy(SendRequestToServer, algo, avaliable);
}

PUBLIC_API ResultCode SeSecStorageIsFactoryResetAlgorithmSupported(FactoryResetAuthAlgo algo, uint32_t *avaliable)
{
    return SeSecStorageIsFactoryResetAlgorithmSupportedProxy(SendRequestToServer, algo, avaliable);
}

PUBLIC_API ResultCode SeSecStorageAllocateSlot(const char *name, const StorageSlotAttr *slotAttr,
    const StorageAuthKey *slotKey)
{
    StorageFileName fileHandle = {0};
    if (memcpy_s(&fileHandle, sizeof(StorageFileName), name, strlen(name)) != EOK) {
        LOG_ERROR("storage name %s is too big", name);
        return INVALID_PARA_ERR_SIZE;
    }

    return SeSecStorageAllocateSlotProxy(SendRequestToServer, &fileHandle, slotAttr, slotKey);
}

PUBLIC_API ResultCode SeSecStorageGetSlotStatus(const char *name, StorageSlotStatus *status)
{
    StorageFileName fileHandle = {0};
    if (memcpy_s(&fileHandle, sizeof(StorageFileName), name, strlen(name)) != EOK) {
        LOG_ERROR("storage name %s is too big", name);
        return INVALID_PARA_ERR_SIZE;
    }
    return SeSecStorageGetSlotStatusProxy(SendRequestToServer, &fileHandle, status);
}

PUBLIC_API ResultCode SeSecStorageWriteSlot(const char *name, const StorageAuthKey *key, uint16_t offset,
    uint16_t length, const StorageDataBuffer *data)
{
    StorageFileName fileHandle = {0};
    if (memcpy_s(&fileHandle, sizeof(StorageFileName), name, strlen(name)) != EOK) {
        LOG_ERROR("storage name %s is too big", name);
        return INVALID_PARA_ERR_SIZE;
    }

    StorageDataArea area = {.offset = offset, .length = length};
    return SeSecStorageWriteSlotProxy(SendRequestToServer, &fileHandle, key, &area, data);
}

PUBLIC_API ResultCode SeSecStorageReadSlot(const char *name, const StorageAuthKey *key, uint16_t offset,
    uint16_t length, StorageDataBuffer *data)
{
    StorageFileName fileHandle = {0};
    if (memcpy_s(&fileHandle, sizeof(StorageFileName), name, strlen(name)) != EOK) {
        LOG_ERROR("storage name %s is too big", name);
        return INVALID_PARA_ERR_SIZE;
    }

    StorageDataArea area = {.offset = offset, .length = length};
    return SeSecStorageReadSlotProxy(SendRequestToServer, &fileHandle, key, &area, data);
}

PUBLIC_API ResultCode SeSecStorageFreeSlot(const char *name, const StorageAuthKey *key)
{
    StorageFileName fileHandle = {0};
    if (memcpy_s(&fileHandle, sizeof(StorageFileName), name, strlen(name)) != EOK) {
        LOG_ERROR("storage name %s is too big", name);
        return INVALID_PARA_ERR_SIZE;
    }

    return SeSecStorageFreeSlotProxy(SendRequestToServer, &fileHandle, key);
}

PUBLIC_API ResultCode SeSecStorageSetAllSlotsSize(const uint16_t *slotSizeArray, uint32_t arrayLength)
{
    return SeSecStorageSetAllSlotsSizeProxy(SendRequestToServer, slotSizeArray, arrayLength);
}

PUBLIC_API ResultCode SeSecStorageGetAllSlotsSize(uint16_t *slotSizeArray, uint32_t *arrayLength)
{
    return SeSecStorageGetAllSlotsSizeProxy(SendRequestToServer, slotSizeArray, arrayLength);
}